
import java.io.IOException;
import java.util.Vector;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;


public class BluetoothDiscovery implements DiscoveryListener {
	
	private Vector _vecDevices;
	private Object _lock;
	private String _connectionURL;
	private LocalDevice _localDevice;
	private DiscoveryAgent _agent;
	
	public BluetoothDiscovery(LocalDevice locDev) {
		_vecDevices = new Vector();
		_lock = new Object();
		_connectionURL = null;
		_localDevice = locDev;
		_agent = _localDevice.getDiscoveryAgent();
	}
	
	public void startDeviceDiscovery() {
		try {
			System.out.println("Address: "+_localDevice.getBluetoothAddress());
			System.out.println("Name: "+_localDevice.getFriendlyName());
			
			System.out.println("\nStating device inquiry...");
			_agent.startInquiry(DiscoveryAgent.GIAC, this);
		} catch (BluetoothStateException e) {
			
		}		
		
		try {
			synchronized (_lock) {
				_lock.wait();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("Device inquiry completed.");
		
		int deviceCount = _vecDevices.size();
		if (deviceCount <= 0) {
			System.out.println("No devices found.");
		}
		else {
			/*System.out.println("\nBluetooth devices:");
			for (int i = 0; i < deviceCount; i++){
				try {
					RemoteDevice remoteDevice = (RemoteDevice) _vecDevices.elementAt(i);
					System.out.println((i+1)+". "+remoteDevice.getBluetoothAddress()+" ("+remoteDevice.getFriendlyName(false)+")");
				} catch (IOException e) {
					
				}
			}*/
		}		
	}
	
	public void startServiceDiscovery(RemoteDevice remoteDevice, String serviceID) {
		UUID[] uuidSet = new UUID[1];
		uuidSet[0] = new UUID(serviceID, true);
	
		try {
			System.out.println("\nSearching for service...");
			_agent.searchServices(null, uuidSet, remoteDevice, this);
		} catch (BluetoothStateException e) {
			
		}
		
		try {
			synchronized (_lock) {
				_lock.wait();
			} 
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
		// TODO Auto-generated method stub
		try {
			System.out.println("Device discovered: "+btDevice.getBluetoothAddress()+" - ("+btDevice.getFriendlyName(false)+")");
		} catch (IOException e) {}
		if (!_vecDevices.contains(btDevice)){
			_vecDevices.addElement(btDevice);
		}
	}

	public void inquiryCompleted(int discType) {
		// TODO Auto-generated method stub
		synchronized (_lock) {
			_lock.notify();
		}
		
		switch (discType) {
			case DiscoveryListener.INQUIRY_COMPLETED:
				System.out.println("INQUIRY_COMPLETED");
				break;
				
			case DiscoveryListener.INQUIRY_TERMINATED:
				System.out.println("INQUIRY_TERMINATED");
				break;
				
			case DiscoveryListener.INQUIRY_ERROR:
				System.out.println("INQUIRY_ERROR");
				break;	
				
			default :
				System.out.println("unknown response code.");
				break;
		
		}
	}

	public void serviceSearchCompleted(int transID, int respCode) {
		// TODO Auto-generated method stub
		synchronized (_lock) {
			_lock.notify();
		}
	}

	public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
		// TODO Auto-generated method stub
		if (servRecord != null && servRecord.length > 0) {
			_connectionURL = servRecord[0].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
		}
		synchronized (_lock) {
			_lock.notify();
		}
	}
	
	public Vector getRemoteDevices() {
		return _vecDevices;
	}
	
	public String getConnectionURL() {
		return _connectionURL;
	}

}
